package kr.or.kosta.otr.controller.usercontroller;

import java.io.IOException;
import java.net.URISyntaxException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.StringTokenizer;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import kr.or.kosta.otr.service.userservice.UserService;
import kr.or.kosta.otr.utill.MessageListVO;
import kr.or.kosta.otr.utill.ReportListVO;
import kr.or.kosta.otr.vo.AdminVO;
import kr.or.kosta.otr.vo.CompanyVO;
import kr.or.kosta.otr.vo.MentorVO;
import kr.or.kosta.otr.vo.MessageTypeVO;
import kr.or.kosta.otr.vo.MessageVO;
import kr.or.kosta.otr.vo.ReportVO;
import kr.or.kosta.otr.vo.TrueOrFalseVO;
import kr.or.kosta.otr.vo.UserVO;

import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class UserController {
	@Resource(name = "UserService")
	UserService userService;

	@Resource(name = "mailSender")
	JavaMailSender mailSender;

	@RequestMapping(value = "/register.action")
	public ModelAndView register(@ModelAttribute UserVO vo) throws SQLException {
		vo.setAdminVo(userService.getAdmin());
		vo.setUserType(userService.getUserType(2).getUserType());
		vo.setUserTypeId(userService.getUserType(2).getUserTypeId());
		userService.register(vo);
		return new ModelAndView("user/register_result");
	}

	@RequestMapping(value = "/userInfo.action")
	public ModelAndView userInfo(HttpSession session) throws SQLException {
		UserVO userVo = (UserVO) session.getAttribute("userVo");
		
		int i = userService.myInterestCompany(userVo.getUserId());
		int j = userService.myInterestReview(userVo.getUserId());
		int x = userService.myCompanyReviewVerifyByUserId(userVo.getUserId());
		ModelAndView mav = new ModelAndView();
		if(i==0)  i=0;
		if(j==0)  j=0;
		if(x==0)  x=0;
		
		mav.addObject("ic", i);
		mav.addObject("ir", j);
		mav.addObject("icr", x/3);
		
		mav.setViewName("user/user_info");
		return mav;
	}

	@RequestMapping(value = "/login.action")
	public ModelAndView login(HttpSession session,
			@RequestParam(value = "id") String id,
			@RequestParam(value = "password") String password)
					throws SQLException {
		HashMap<String, String> map = new HashMap<String, String>();
		map.put("userId", id);
		map.put("userPassword", password);
		map.put("adminId", id);
		map.put("adminPassword", password);
		
		UserVO uvo = userService.userlogin(map);
		AdminVO avo = userService.adminlogin(map);

		boolean flag = false;

		int message=0;
		if (uvo != null){
			message =userService.getMessageCount(uvo.getUserId());
			uvo.setMessage(message);
			session.setAttribute("userVo", uvo);
			flag = true;
		}else if (avo != null){
			message = userService.getReportCount(avo.getAdminId());
			avo.setMessage(message);
			session.setAttribute("adminVo", avo);
			flag = true;
		}
		//return new ModelAndView("index/index");
		ModelAndView mv = new ModelAndView("JsonView");
		mv.addObject("flag",flag);
		return mv;
	}

	@RequestMapping(value = "/isexist.action")
	public ModelAndView isExist(@RequestParam(value = "userId") String userId)
			throws SQLException {
		boolean flag = userService.isExist(userId);
		return new ModelAndView("JsonView", "flag", flag);
	}

	@RequestMapping(value="/findId.action")
	public ModelAndView findId(@RequestParam(value="email")String email)
			throws SQLException,URISyntaxException, MessagingException, IOException{
		
		ModelAndView mv = new ModelAndView();
		
		UserVO vo = userService.findId(email);
		System.out.println("userVo:: " + vo);
		if(vo != null){
			MimeMessage message = mailSender.createMimeMessage();
			MimeMessageHelper messageHelper = new MimeMessageHelper(message,true,"UTF-8");
			messageHelper.setFrom("zhtmxj23@naver.com"); // 보내는 사람
			String to = email;
			messageHelper.setTo(new InternetAddress(to)); // 받는 사람
			messageHelper.setSubject("[알림] OfftheRecord 아이디"); // 제목
			messageHelper.setText(vo.getUserId()); // 내용
			
			mv.setViewName("user/find_user_result");
			
			try{
				mailSender.send(message);
			}
			catch (Exception me) { 
				me.printStackTrace();
			}
		}else if(vo == null){
			System.out.println("들어왔나?");
			String error = "email";
			mv.addObject("error",error);
			mv.setViewName("error");
		}
		
		
		return mv;
	}
	@RequestMapping(value="/findPassword.action")
	public ModelAndView findPassword(@RequestParam(value="id")String id) 
			throws SQLException,URISyntaxException, MessagingException, IOException {
		UserVO vo = userService.findPassword(id);

		if(vo.getUserId() != null){
			MimeMessage message = mailSender.createMimeMessage();
			MimeMessageHelper messageHelper = new MimeMessageHelper(message,true,"UTF-8");
			messageHelper.setFrom("zhtmxj23@naver.com"); // 보내는 사람
			String to = vo.getUserEmail();
			messageHelper.setTo(new InternetAddress(to)); // 받는 사람
			messageHelper.setSubject("[알림] OfftheRecord 비밀번호"); // 제목
			messageHelper.setText(vo.getUserPassword()); // 내용
			

			try{
				mailSender.send(message);
			}
			catch (Exception me) { 
				me.printStackTrace();
			}
		}
		return new ModelAndView("user/find_user_result");
	}

	@RequestMapping(value = "logout.action")
	public ModelAndView logout(HttpSession session) throws SQLException {
		session.invalidate();

		return new ModelAndView("index/index");
	}
	@RequestMapping(value = "getAllMessage.action")
	public ModelAndView getAllMessage(HttpSession session, @RequestParam("mpageNo") String mpageNo) throws SQLException {
		UserVO userVo = (UserVO) session.getAttribute("userVo");
		AdminVO adminVo = (AdminVO) session.getAttribute("adminVo");

		ModelAndView mav = new ModelAndView();
		HashMap<String, Object> mur = new HashMap<String, Object>();
		
		if(userVo != null && adminVo == null){
			ArrayList<MessageVO> muslist = new ArrayList<MessageVO>();
			ArrayList<ReportVO> maslist = new ArrayList<ReportVO>();
			
			mur.put("userId", userVo.getUserId());
			mur.put("value", mpageNo);
			MessageListVO murlist = userService.getAllMessagePage(mur);
			muslist = userService.getAllSendMessage(userVo.getUserId());
			maslist = userService.getAllUserSendMessage(userVo.getUserId());
			mav.addObject("mrlist", murlist);
			mav.addObject("mslist", muslist);
			mav.addObject("maslist", maslist);
			mav.setViewName("user/user_message");
		}else if(userVo == null && adminVo != null){
			// ArrayList<ReportVO> mrlist = new ArrayList<ReportVO>();
			ArrayList<MessageVO> maslist = new ArrayList<MessageVO>();
			mur.put("adminId", adminVo.getAdminId());
			mur.put("value", mpageNo);
			ReportListVO mrlist = userService.getAllReportPage(mur);
			maslist = userService.getAllSendMessage(adminVo.getAdminId());
			mav.addObject("mrlist", mrlist);
			mav.addObject("maslist", maslist);
			mav.setViewName("admin/admin_message");
		}


		return mav;
	}
	@RequestMapping(value="deleteMessage.action")
	public ModelAndView deleteMessage(@RequestParam(value="messageId") int messageId,HttpSession session) throws SQLException {

		UserVO uvo = (UserVO) session.getAttribute("userVo");
		AdminVO avo = (AdminVO) session.getAttribute("adminVo");

		int message=0;
		if (uvo != null){
			userService.deleteMessage(messageId);
			message =userService.getMessageCount(uvo.getUserId());
			uvo.setMessage(message);
			session.setAttribute("userVo", uvo);
		}
		else{
			userService.deleteReport(messageId);
			message = userService.getReportCount(avo.getAdminId());
			avo.setMessage(message);
			session.setAttribute("adminVo", avo);
		}
		return new ModelAndView("forward:/getAllMessage.action?mpageNo=1");
	}
	@RequestMapping(value="checkMessage.action")
	public ModelAndView checkMessage(@RequestParam(value="messageId") int messageId,HttpSession session) throws SQLException {
		
		UserVO uvo = (UserVO) session.getAttribute("userVo");
		AdminVO avo = (AdminVO) session.getAttribute("adminVo");

		int message=0;
		if (uvo != null){
			HashMap<String, Object> map = new HashMap<String, Object>();
			map.put("messageId", messageId);
			map.put("userId", uvo.getUserId());
			userService.checkMessage(map);
			message =userService.getMessageCount(uvo.getUserId());
			uvo.setMessage(message);
			session.setAttribute("userVo", uvo);
		}
		if (avo != null){
			HashMap<String, Object> map = new HashMap<String, Object>();
			map.put("reportId", messageId);
			map.put("adminId", avo.getAdminId());
			userService.checkReport(map);			
			message = userService.getReportCount(avo.getAdminId());
			avo.setMessage(message);
			session.setAttribute("adminVo", avo);
		}
		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("ch", "Y");
		map.put("message", message);
		return new ModelAndView("JsonView", "message", map);
	}
	@RequestMapping(value = "getAllCompanyReviewByUserId.action")
	public ModelAndView getAllCompanyReviewByUserId(HttpSession session, @RequestParam("pageNo")String pageNo) throws SQLException {
		UserVO userVo = (UserVO) session.getAttribute("userVo");
		ModelAndView mv = new ModelAndView();
		
		//Total
		double Total = userService.getCompanyReviewVerifyByUserIdTotal(userVo.getUserId());
		
		mv.addObject("page", Math.ceil(Total/9));
		mv.addObject("nowPage", pageNo);
		//companyReviewVerify 가져오기
		//ArrayList<TrueOrFalseVO> crvList = userService.getCompanyReviewVerifyByUserId(userVo.getUserId());
		HashMap<String, Object> hmap = new HashMap<String, Object>();
		hmap.put("userId", userVo.getUserId());
		hmap.put("value", pageNo);
		ArrayList<TrueOrFalseVO> crvList = userService.getCompanyReviewVerifyByUserIdPage(hmap);
		LinkedHashMap<String, ArrayList<TrueOrFalseVO>> linkmap = new LinkedHashMap<String, ArrayList<TrueOrFalseVO>>();
		int count=1;

		//진실 혹은 거짓 바인딩

		for (int i = 0; i < crvList.size();) {
			//각 리뷰에 대한 바인딩
			String userId = count
					+ " "
					+ crvList.get(i).getCompanyReviewVerifyVO()
					.getCompanyReviewVO().getCompanyReviewUserId();
			ArrayList<TrueOrFalseVO> tfList = new ArrayList<TrueOrFalseVO>();
			// 리뷰 진실 거짓 값 넣어주기

			//truth(진실)을 누른사람들을 넣은 것 -> 이거를 토크나이저로 잘라 숫자를 센다.
			String truth = crvList.get(i).getTruth();
			StringTokenizer tk1 = new StringTokenizer(truth, ",");

			int countT = 0;

			while (tk1.hasMoreTokens()) {
				countT++;
				tk1.nextToken();
			}
			crvList.get(i).setT(countT);

			//objection을 누른 사람들을 토크나이저로 잘라 수를 세서 o 에 바인딩
			String objection = crvList.get(i).getObjection();
			int countF = 0;
			StringTokenizer tk2 = new StringTokenizer(objection, ",");
			while (tk2.hasMoreTokens()) {
				countF++;
				tk2.nextToken();
			}
			crvList.get(i).setO(countF);

			tfList.add(crvList.get(i++));
			// 장점 진실 거짓 값 넣어주기
			String js = crvList.get(i).getTruth();
			int jconutT = 0;
			StringTokenizer jtk1 = new StringTokenizer(js, ",");
			while (jtk1.hasMoreTokens()) {
				jconutT++;
				jtk1.nextToken();
			}
			crvList.get(i).setT(jconutT);

			String job = crvList.get(i).getObjection();
			int jocountF = 0;
			StringTokenizer jtk2 = new StringTokenizer(job, ",");
			while (jtk2.hasMoreTokens()) {
				jocountF++;
				jtk2.nextToken();
			}
			crvList.get(i).setO(jocountF);

			tfList.add(crvList.get(i++));

			// 거짓 진실 거짓 값 넣어주기
			String ks = crvList.get(i).getTruth();
			int kcountT = 0;
			StringTokenizer ktk1 = new StringTokenizer(ks, ",");
			while (ktk1.hasMoreTokens()) {
				kcountT++;
				ktk1.nextToken();
			}
			crvList.get(i).setT(kcountT);

			String kob = crvList.get(i).getObjection();
			int kcountF = 0;
			StringTokenizer ktk2 = new StringTokenizer(kob, ",");
			while (ktk2.hasMoreTokens()) {
				kcountF++;
				ktk2.nextToken();
			}
			crvList.get(i).setO(kcountF);

			tfList.add(crvList.get(i++));


			linkmap.put(userId, tfList);
			count++;
		}

		mv.addObject("crv", linkmap);
		mv.setViewName("user/user_review");
		return mv;
	}

	@RequestMapping(value="/writeReport.action")
	public ModelAndView writeReport(
			@ModelAttribute ReportVO rvo,
			HttpSession session) throws SQLException {
		UserVO userVo = (UserVO) session.getAttribute("userVo");

		AdminVO adminVo = userVo.getAdminVo();
		rvo.setAdminVo(adminVo);
		rvo.setReportSender(userVo.getUserId());
	
		userService.writeReport(rvo);
		
		return new ModelAndView("user/find_user_result");
	}

	//message
	@RequestMapping(value="/getMessageType.action")
	public ModelAndView getMessageType(
			@RequestParam(value="type") String type,
			HttpServletRequest request)
			throws SQLException{

		ModelAndView mv = new ModelAndView("user/user_write_message");

		//receiver 바인딩
		String receiver = request.getParameter("receiver");
		if(receiver != null){
			mv.addObject("receiver", receiver);
		}
		
		//type에 따라 목록 다르게 바인딩
		ArrayList<MessageTypeVO> mtList = new ArrayList<MessageTypeVO>();
		HashMap<String, Object> map = new HashMap<String, Object>();
		if(type.equals("1")){
			
			map.put("messageType", "message_type_id");
			map.put("messageTypeValue", 1);
			
			MessageTypeVO mtvo = userService.getMessageType(map);
			mtList.add(mtvo);
			
			mv.addObject("mtList", mtList);
		}else if(type.equals("2")){
			map.put("messageType", "message_type_id");
			map.put("messageTypeValue", 3);
			
			MessageTypeVO mtvo = userService.getMessageType(map);
			mtList.add(mtvo);
			
			mv.addObject("mtList", mtList);
		}
		return mv;
	}

	@RequestMapping(value="/writeMessageByUser.action")
	public ModelAndView writeMessageByUser(@ModelAttribute MessageVO mvo,
			@RequestParam(value="messageTypeNum")String messageTypeNum,
			HttpSession session
			) throws SQLException{
		//보낸이 바인딩
		UserVO userVo = (UserVO) session.getAttribute("userVo");
		AdminVO adminVo = (AdminVO) session.getAttribute("adminVo");

		if(userVo != null){
			mvo.setMessageReceiver(userVo.getUserId());
		}else if(adminVo != null){
			mvo.setMessageReceiver(adminVo.getAdminId());
		}
		String sender = mvo.getMessageSender(); // 받는이
		String receiver = mvo.getMessageReceiver(); // 보낸이
		if(sender != null && receiver != null){
			if(receiver.equals(userVo.getUserId())){
				HashMap<String, Object> mmap = new HashMap<String, Object>();
				mmap.put("userId", receiver);
				mmap.put("point", 10);
				HashMap<String, Object> pmap = new HashMap<String, Object>();
				pmap.put("userId", sender);
				pmap.put("point", 20);
				userService.updatePointMinus(mmap);
				userService.updatePointPlus(pmap);
			
				int point = userService.getUserPoint(userVo.getUserId());
				userVo.setUserPoint(point);
			}
			else{
				HashMap<String, Object> mmap = new HashMap<String, Object>();
				mmap.put("userId", receiver);
				mmap.put("point", 20);
				HashMap<String, Object> pmap = new HashMap<String, Object>();
				pmap.put("userId", sender);
				pmap.put("point", 10);
				userService.updatePointMinus(pmap);
				userService.updatePointPlus(mmap);
				
				int point = userService.getUserPoint(userVo.getUserId());
				userVo.setUserPoint(point);
			}
		}
		//메시지 타입 바인딩
		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("messageType", "message_type_num");
		map.put("messageTypeValue", messageTypeNum);
		MessageTypeVO mtvo = userService.getMessageType(map);
		mvo.setMessageTypeVo(mtvo);
	
		userService.writeMessage(mvo);
		
		return new ModelAndView("user/find_user_result");
	}

	@RequestMapping(value="/report.action")
	public ModelAndView Report(
			@RequestParam(value="id")int messageId,
			HttpSession session) throws SQLException {

		UserVO userVo = (UserVO) session.getAttribute("userVo");
		MessageVO message = userService.getOneMessage(messageId);
		ReportVO re = new ReportVO(0, userVo.getAdminVo(), userVo.getUserId(), message.getMessageReceiver(), "불량 회원을 신고 합니다.");
		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("point", 20);
		map.put("userId", message.getMessageReceiver());
		userService.updatePointMinus(map);
		userService.writeReport(re);
		
		return new ModelAndView("JsonView");
	}


	@RequestMapping(value="/deleteUser.action")
	public ModelAndView deleteUser(HttpSession session) throws SQLException {

		UserVO userVo = (UserVO) session.getAttribute("userVo");

		userService.deleteUser(userVo.getUserId());
		session.invalidate();

		return new ModelAndView("index/index");
	}


	@RequestMapping(value="/updateUser.action")
	public ModelAndView updateUser(@ModelAttribute UserVO userVo,
			HttpSession session
			) throws SQLException {

		//update
		userService.updateUser(userVo);
		UserVO vo = (UserVO) session.getAttribute("userVo");
		vo.setUserEmail(userVo.getUserEmail());
		vo.setUserPassword(userVo.getUserPassword());

		return new ModelAndView("user/user_update");
	}

	@RequestMapping(value="/mentorReport.action")
	public ModelAndView mentorReport(
			@ModelAttribute ReportVO rvo,
			HttpSession session) throws SQLException {

		UserVO userVo = (UserVO) session.getAttribute("userVo");
		AdminVO adminVo = userVo.getAdminVo();
		rvo.setAdminVo(adminVo);
		rvo.setReportSender(userVo.getUserId());
		userService.writeReport(rvo);
		
		return new ModelAndView("mentor/mentor_apply_result");
	}

	@RequestMapping(value="/getMentorByCompany.action")
	public ModelAndView getMentorByCompany(
			@RequestParam(value="companyName") String companyName) throws SQLException {

		ModelAndView mv = new ModelAndView("mentor/mentor_search");
		HashMap<String, Object> map = new HashMap<String, Object>();
	
		map.put("company", "company_name");
		map.put("companyValue", companyName);
		ArrayList<CompanyVO> clist = userService.getCompanyInfo(map);
		if(clist.isEmpty()){
			String message = "해당 기업이 존재하지 않습니다.";
			mv.addObject("message",message);
		}
		
		map.put("company", "company_name");
		map.put("companyValue", companyName);
		ArrayList<MentorVO> mList = userService.getAllMentor(map);

		mv.addObject("mList",mList);

		return mv;
	}
	
	

	@RequestMapping(value="/sendReport.action")
	public ModelAndView sendReport(
			@RequestParam(value="reportContent")String reportContent,
			HttpSession session) throws SQLException {

		UserVO userVo = (UserVO) session.getAttribute("userVo");
		AdminVO adminVo = (AdminVO) session.getAttribute("adminVo");
		String message = null;
		if(userVo == null && adminVo == null){
			message = "로그인 후 작성해 주세요.";
		}else if(adminVo != null && userVo == null){
			message = "관리자는 작성할 수 없습니다.";
		}else if(userVo != null && adminVo == null){
			ReportVO rvo = new ReportVO(userVo.getAdminVo(), userVo.getUserId(), null, reportContent);
			userService.writeReport(rvo);
			message = "건의사항이 접수되었습니다.";
		}
		
		return new ModelAndView("JsonView","message",message);
	}
	@RequestMapping(value = "/deleteMyReview.action")
	public ModelAndView deleteInterestCompany(@RequestParam(value="companyReviewId") int companyReviewId) throws SQLException {

		userService.deleteCompanyReview(companyReviewId);
		return new ModelAndView("forward:/getAllCompanyReviewByUserId.action?pageNo=1");
	}
}
